package net.tycmc.cty.ctyms.timejob.iems.service;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import com.tycmc.functions.MapFunction;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.tycmc.bulb.common.util.DateUtil;
import net.tycmc.bulb.common.util.MapGetter;
import net.tycmc.bulb.common.util.StringUtil;
import net.tycmc.cty.ctyms.timejob.common.LogUtil;
import net.tycmc.cty.ctyms.timejob.common.MailCfg;
import net.tycmc.cty.ctyms.timejob.common.MsgTobaidyun;
import net.tycmc.cty.ctyms.timejob.iems.dao.AlarmFunctionDiagnosisDAO;
import net.tycmc.cty.ctyms.timejob.iems.dao.MtnFaultDao;
import net.tycmc.cty.ctyms.timejob.iems.dao.SMSInfoDAO;

/**
 * 故障报警相关业务逻辑操作
 * @author fengJie
 *@modify chengShiChao	增加故障报警状态初始化	2011-10-14
 *@modify chengShiChao	增加故障报警、保养提醒信息的短信发送和保养预测轮询	2011-10-22
 *@remark 故障报警、保养提醒的程序轮询时间间隔5分钟，保养预测程序轮询时间间隔1小时
 */
public class MtnFaultServcie {
	
	private MtnFaultDao malfunctionDiagnosisDAO;
	private AlarmFunctionDiagnosisDAO alarmDAO;
	private SMSInfoDAO smsInfoDAO;
	private static List<String[]> poiss = null;

	public AlarmFunctionDiagnosisDAO getAlarmDAO() {
		return alarmDAO;
	}

	public void setAlarmDAO(AlarmFunctionDiagnosisDAO alarmDAO) {
		this.alarmDAO = alarmDAO;
	}

	public MtnFaultDao getMalfunctionDiagnosisDAO() {
		return malfunctionDiagnosisDAO;
	}

	public void setMalfunctionDiagnosisDAO(
			MtnFaultDao malfunctionDiagnosisDAO) {
		this.malfunctionDiagnosisDAO = malfunctionDiagnosisDAO;
	}
	
	

	public SMSInfoDAO getSmsInfoDAO() {
		return smsInfoDAO;
	}

	public void setSmsInfoDAO(SMSInfoDAO smsInfoDAO) {
		this.smsInfoDAO = smsInfoDAO;
	}

	/**
	 * 测试连接CTYMS库
	 * 
	 * @return
	 */
	public List<Map<String, Object>> getTestCTYMS() {
		return this.getMalfunctionDiagnosisDAO().getTestCTYMS();
	}
	
	//故障状态初始化及线性故障信息发送
	public void calFaultStateHandle(Map<String,String> map) throws ParseException{
		//从故障信息表取数据
        		List<Map<String,Object>> list = malfunctionDiagnosisDAO.getFaultDataAB(map);
		/*wangkai20141016新增故障提示开关判断，判断逻辑如下
		 * 3.6.6新增
		 * 1，从提示开关表中获取“故障提示开关”为关的设备集合
		   2，对从list进行遍历，如果存在则移除该设备的信息
		*/
		//获取所有账户对应的百度id和频道id
		Map <String,Map<String,Object>> mapAccountid =malfunctionDiagnosisDAO.getAllAccountMsg();
		//获取手机App人员及对应配置的故障级别(管理版)
		Map<String,List<Map<String,Object>>> mapUserMsg=getAllUserMsgs(1);
		
		//获取手机App人员及对应配置的故障级别(支持版)
		Map<String,List<Map<String,Object>>> mapUserMsgSp=getAllUserMsgs(2);
		//定义一个list,存储配置好的信息进行云推送(管理版)
		List<Map<String,Object>> CloudPushlistMa=new ArrayList<Map<String,Object>>();
		//定义一个list,存储配置好的信息进行云推送(支持版)
		List<Map<String,Object>> CloudPushlistSp=new ArrayList<Map<String,Object>>();
		/******************获取故障提示开关为关的设备id的集合begin******************/
		List<String> FltPromptSwitchDown = malfunctionDiagnosisDAO.getFLtPromtPSwitch();
		/******************获取故障提示开关为关的设备id的集合end********************/
		/******************位置点获取BEGIN*********************************/
		List<String[]> poi = new ArrayList<String[]>();
		for(Map<String,Object> ll : list){
			/*判断故障信息集合list中是否存在故障提示开关为关的设备id，如果存在则不做处理wangkai20141016*/
			if(!FltPromptSwitchDown.contains(MapGetter.getString(ll, "VehicleID"))){
				poi.add(new String[]{MapGetter.getString(ll, "MessageID"),MapGetter.getString(ll, "MsgF_Lo"),MapGetter.getString(ll, "MsgF_La")});
			}
		}
		if(poi.size()>=1){
			ExecutorService exec = Executors.newCachedThreadPool();
			selectPosition(exec,20000,poi);
			exec.shutdown();
		}
		/*if(null != poiss){
			for(int i=0;i<list.size();i++){
				if(0 == poiss.size()) break;
				for(int j=0;j<poiss.size();j++){
					if(MapGetter.getString(list.get(i), "MessageID").equals(poiss.get(j)[0])){
						list.get(i).put("Position",poiss.get(j)[1]);
						poiss.remove(j);
						break;
					}
				}
			}
		}*/
		/*判断故障信息集合list中是否存在故障提示开关为关的设备id，如果存在则不做处理wangkai20141016*/
		if(null != poiss){
			for(int i=0;i<list.size();i++){
				if(0 == poiss.size()) break;
				for(int j=0;j<poiss.size();j++){
					if(!FltPromptSwitchDown.contains(MapGetter.getString(list.get(i), "VehicleID"))){
						if(MapGetter.getString(list.get(i), "MessageID").equals(poiss.get(j)[0])){
							list.get(i).put("Position",poiss.get(j)[1]);
							poiss.remove(j);
							break;
						}
					}
				}
			}
		}
		/******************位置点获取END*********************************/
		
		LogUtil.info(this.getClass().getName(), "End -- 故障捕获结束，共捕获到‘"+list.size()+"’条故障信息！");
		/**2013.04.12 haoyang add begin*/
		//获取25分 前的短信发送记录(故障报警,故障解除):粗略过滤作用
		List<String> fltSendRecord = smsInfoDAO.getSmsMsgBeforeSomeTime("1");
		List<String> fltRelsSendRecord = smsInfoDAO.getSmsMsgBeforeSomeTime("7");
		//第二天短信发送记录
		List<String> fltSendRecordSecDay = smsInfoDAO.getSmsMsgSecondDay("1");
		List<String> fltRelsSendRecordSecDay = smsInfoDAO.getSmsMsgSecondDay("7");
		//利用list 判断同设备同故障 是否发送过短信(判断本次扫描的数据)
		List<String> fltList = new ArrayList<String>();
		List<String> fltRelsList = new ArrayList<String>();//vclid_fltcode:同一设备同一故障
		//2013.05.31 add 从业务库新建表[Sys_FltISMLast] 中取故障 信息 集合，表中仅存入线性故障
		Map<String,String> fltTimesMap = malfunctionDiagnosisDAO.getFltTimesFromMsgP();//获取 业务表中次数信息（最新）
		
		Map<String,Map<String,Object>> fltTimesMaps = new HashMap<String,Map<String,Object>>();//获取 业务表中次数信息（最新）
		
		Map<String,Map<String,Object>> NofltTimesMaps = new HashMap<String,Map<String,Object>>();//非线性集合
		
		//Map<String,String> fltTimesMap=new HashMap<String,String>();
		// 获取配置的发送时间
		List<String> smsSendTimeList = smsInfoDAO.getSMSCfgSendTime("1");
		
		/**end*/
		int xxFlt = 0;		//报警中条数；
		int xxSuc = 0;		//插入状态表成功条数
		int xxFail = 0;		//插入状态表失败条数
		int xxMsgSuc = 0;	//短信成功发送次数
		int xxMsgFail = 0;	//短信发送失败次数

		int fxxFlt = 0;		//报警解除条数；
		int fxxSuc = 0;		//报警解除成功条数；
		int fxxFail = 0;	//报警解除失败条数；
		
		//遍历数据
 		for(Map<String,Object> hm:list){
			List<String> sqlList = new ArrayList<String>();
			List<Object[]> paramList = new ArrayList<Object[]>();
			//判断故障信息集合list中是否存在故障提示开关为关的设备id，如果存在则不做处理wangkai20141016
			if(!FltPromptSwitchDown.contains(MapGetter.getString(hm, "VehicleID"))){
				// 获得设备所属机构Code值
				Map<String, Object> codeMap = malfunctionDiagnosisDAO.getDBCode(MapGetter.getString(hm, "VehicleID"));
				//获取故障码
				String FltCode = MapGetter.getString(hm, "FaultCode");
				// 获取设备组织机构
				String DBCode = MapGetter.getString(codeMap, "DBCode");
				//获取设备ID
				String VehicleID = MapGetter.getString(hm, "VehicleID"); 
				List<Map<String,Object>> userList = smsInfoDAO.getSMSUsers_Flt(FltCode,DBCode,VehicleID,"SMSAS_SMSFlt",false);
				String Fltlevel=MapGetter.getString(hm, "sysism_level");
				String FaultType = hm.get("FaultTypeID")!=null?hm.get("FaultTypeID").toString():"";
				String spn=MapGetter.getString(hm, "SysISM_SPN" );
				String fmi=MapGetter.getString(hm,"SysISM_FMI");
				if(FaultType.equals("0")){//故障类型为现行，为该故障初始化状态,同时发送短信
					//2013.05.31 add vclID_fltCode_fltTimes 过滤 begin
					String vclId_fltCode = MapGetter.getString(hm,"vclId_fltCode");
					String fltTimes = MapGetter.getString(hm,"fltTimes");
					if(fltTimesMap.containsKey(VehicleID+"_"+spn+"_"+fmi)&&fltTimesMap.get(VehicleID+"_"+spn+"_"+fmi).equals(fltTimes)){
							continue;	
					}else{
							fltTimesMap.put(VehicleID+"_"+spn+"_"+fmi,fltTimes );
							fltTimesMaps.put(VehicleID+"_"+spn+"_"+fmi, hm);
							NofltTimesMaps.remove(VehicleID+"_"+spn+"_"+fmi);
						
					}
					
					//2013.05.31 add vclID_fltCode_fltTimes 过滤 end
					//将该车之前的在报警中的该故障全部更新为已解除。解除方式自动，解除时间同新故障的时间。--3.4.1  LXF add
					malfunctionDiagnosisDAO.updateFaultState(sqlList,paramList,hm);
					xxFlt++;
					//状态初始化 故障表中存在否
					boolean flag = malfunctionDiagnosisDAO.addFaultState(sqlList,paramList,hm);
					//状态初始化成功则发送报警短信
					if(flag){
						//添加成功，需要 将本次 vclId_fltCode_fltTimes添加到fltTimes
						xxSuc++;
						//邮件发送--------改为日报，不实时发送--------------------------
						
						
	//					List<Map<String,Object>> userMailList = smsInfoDAO.getSMSUsers(DBCode, "SMSAS_MailFlt");//邮件接收人
	//					
	//					mailSuje = MailCfg.getMailSujeInfo(MapGetter.getString(codeMap, "VehicleNumber"),
	//							MapGetter.getString(hm, "MessageTime"), MailCfg.MailSujeFlt); //邮件主题初始化
	//					
	//					mailContent = SMSContentCfg.SMSCCfgFlt.replace("X_VclNum", MapGetter.getString(codeMap, "VehicleNumber"))
	//							.replace("X_Date", DateList.getFormatDate(MapGetter.getString(hm, "MessageTime"),5))
	//							.replace("X_FltCode", MapGetter.getString(hm, "FaultCode")).replace("X_Content", MapGetter.getString(hm, "FltISM_ContentCN_Abbr"));//邮件内容初始化
	//					
	//					SendMail.getInstance().sendMail(mailSuje, mailContent, userMailList, "Email");//发送邮件，暂未对发送状态进行判断处理
	//					
						//邮件发送----------------------------------
						
						//发送故障信息,同步更新短信接收人
						//2013.04.12 haoyang
						boolean isSuc = false;
						
						String uniqueID = MapGetter.getString(hm, "VehicleID")+"_"+MapGetter.getString(hm, "FaultCode");
						if(!fltList.contains(uniqueID)&&!fltSendRecord.contains(uniqueID)&&!fltSendRecordSecDay.contains(uniqueID)){
							isSuc = malfunctionDiagnosisDAO.sendFaultInfo(sqlList,paramList,hm,userList,smsSendTimeList,"1");
						}

						//App推送(管理)
						List<Map<String,Object>> listss=mapUserMsg.get(VehicleID);
						//App推送(支持)
						List<Map<String,Object>> listssSp=mapUserMsgSp.get(VehicleID);
						//管理版
						InsertApp(listss, hm, sqlList, paramList,CloudPushlistMa,mapAccountid,1);
						//支持版
						InsertApp(listssSp, hm, sqlList, paramList,CloudPushlistSp,mapAccountid,2);
						
						if(isSuc){
							xxMsgSuc++;
							fltList.add(uniqueID);
						}else{
							xxMsgFail++;
						}
					}else{
						xxFail++;
					}
				}else{//故障类型为非线性，更新之前所有该类型为报警中的故障数据，将其状态更新为已解除
					fxxFlt++;
					/**2013.03.29 haoyang 新增,判断是否发生 故障解除短信 begin*/
					String vclId = MapGetter.getString(hm, "VehicleID");//设备id.
					String fltCode = MapGetter.getString(hm, "FaultCode");//故障代码
					String vclId_fltCode = MapGetter.getString(hm,"vclId_fltCode");
					fltTimesMaps.remove(VehicleID+"_"+spn+"_"+fmi);
					NofltTimesMaps.put(VehicleID+"_"+spn+"_"+fmi,hm );
					
					if(!StringUtil.isNullOrEmpty(vclId)||!StringUtil.isNullOrEmpty(fltCode)){
						continue;
					}
					//1.判断提示列表中,(该设备该故障) 是否存在未解除的信息
					if(!malfunctionDiagnosisDAO.isExist(vclId, fltCode)){ 
						//1.1 若不存在,说明(该设备该故障)记录上一条信息为 非线性故障;continue
						continue;
					}
					//1.2 若存在,说明(该设备该故障)记录上一条信息为 线性故障;
					//1.2.1 将未解除故障 解除
					String lastRelsTime = malfunctionDiagnosisDAO.getLastRelsTime(hm);//获取 上次的解除时间
					boolean flag = malfunctionDiagnosisDAO.updateFaultState(sqlList,paramList,hm);
					hm.put("LastRelsTime",lastRelsTime );
					hm.put("MsgP_Type",1 );
					if(flag){
						fltTimesMap.remove(VehicleID+"_"+spn+"_"+fmi);
						//邮件发送------改为日报，不实时发送----------------------------
						
	//					List<Map<String,Object>> userMailList = smsInfoDAO.getSMSUsers(DBCode, "SMSAS_MailRels");//邮件接收人
	//					
	//					mailSuje = MailCfg.getMailSujeInfo(MapGetter.getString(codeMap, "VehicleNumber"),
	//							MapGetter.getString(hm, "MessageTime"), MailCfg.MailSujeFltRels); //邮件主题初始化
	//					
	//					mailContent = SMSContentCfg.SMSCCfgFltRels.replace("X_VclNum", MapGetter.getString(codeMap, "VehicleNumber"))
	//								.replace("X_Date", DateList.getFormatDate(MapGetter.getString(hm, "MessageTime"),5))
	//								.replace("X_FltCode", MapGetter.getString(hm, "FaultCode"));//邮件内容初始化
	//					
	//					SendMail.getInstance().sendMail(mailSuje, mailContent, userMailList, "Email");//发送邮件，暂未对发送状态进行判断处理
						
						//邮件发送----------------------------------
						
						boolean isSuc = false;
						String uniqueID = MapGetter.getString(hm, "VehicleID")+"_"+MapGetter.getString(hm, "FaultCode");
						if(!fltRelsList.contains(uniqueID)&&!fltRelsSendRecord.contains(uniqueID)&&!fltRelsSendRecordSecDay.contains(uniqueID))
							isSuc = malfunctionDiagnosisDAO.sendFaultInfo(sqlList,paramList,hm,userList,smsSendTimeList,"7");
						if(isSuc)
							fltRelsList.add(uniqueID);
					}
					/** end */
					if(flag)
						fxxSuc++;
					else
						fxxFail++;
				}
				if(sqlList.size()>0){
					boolean flag = malfunctionDiagnosisDAO.tranSQLs(sqlList, paramList);
					String MessageID = MapGetter.getString(hm, "MessageID");
					if(!flag){
						LogUtil.info(this.getClass().getName(), "故障---------设备ID:"+VehicleID+";MessageID:"+MessageID+",插入提示信息表失败！");
					}
				}
				/*boolean flags = malfunctionDiagnosisDAO.updateFltPosition(MapGetter.getString(hm, "MessageTime"), MapGetter.getString(hm, "VehicleID"));
				String MessageID = MapGetter.getString(hm, "MessageID");
				if(!flags){
				LogUtil.info(this.getClass().getName(), "故障---------设备ID:"+VehicleID+";MessageID:"+MessageID+",更新提示信息表位置信息失败！");
				}*/
				sqlList = null;
				paramList = null;
				
			}
		}
		List<String> sqlListone = new ArrayList<String>();
		List<Object[]> paramListone = new ArrayList<Object[]>();
		//更新现行故障
		malfunctionDiagnosisDAO.InsertFltMsg(fltTimesMaps,sqlListone,paramListone);
		//删除线性
		malfunctionDiagnosisDAO.delFltMsg(NofltTimesMaps, sqlListone, paramListone);
		if(sqlListone.size()>0){
			boolean flag = malfunctionDiagnosisDAO.tranSQLs(sqlListone, paramListone);
			if(flag){
				LogUtil.info(this.getClass().getName(), "Msg_Flt_HappeningLast表更新成功，共更新"+(fltTimesMaps.size()+NofltTimesMaps.size())+"条");
			}
		}
		//调用百度云，发送App信息给用户(管理版)
		new MsgTobaidyun().sendMsg(CloudPushlistMa);
		//调用百度云，发送App信息给用户(支持版)
		new MsgTobaidyun().sendMsg(CloudPushlistSp);
		fltSendRecord = null;
		fltRelsSendRecord = null;
		fltSendRecordSecDay = null;
		fltRelsSendRecordSecDay = null;
		fltList = null;
		fltRelsList = null;
		fltTimesMap = null;
		LogUtil.info(this.getClass().getName(), "故障---------处于报警中的信息共有‘"+xxFlt+"’条，插入状态表成功‘"+xxSuc+"’条，失败‘"+xxFail+"’条，‘"+xxMsgSuc+"’条故障信息发送短信成功，‘"+xxMsgFail+"’条故障信息发送短信失败；" +
				"共有故障解除数据‘"+fxxFlt+"’条，‘"+fxxSuc+"’条故障解除修改成功（同一设备,同一故障,连续解除,不再计数），‘"+fxxFail+"’条故障解除失败！");
		
		System.out.println("故障执行完毕--------------------------------------------------------------");
		
	}
	
	private Boolean selectPosition(ExecutorService exec, int timeout, List<String[]> poi) {
		SelectPois sPois = new SelectPois(poi);
		Future<Boolean> future = exec.submit(sPois);
		Boolean result = null;
		try {
			result = future.get(timeout,TimeUnit.MILLISECONDS);
		} catch (InterruptedException e) {
			exec.shutdownNow();
			e.printStackTrace();
		} catch (ExecutionException e) {
			exec.shutdownNow();
			e.printStackTrace();
		} catch (TimeoutException e) {
			exec.shutdownNow();
			e.printStackTrace();
		}
		return result;
	}

	/**
	 * 机械报警状态初始化及报警信息发送短信
	 */
	public void calAlarmStateHandle(Map<String,String> hm){
		//从报警表获取最新报警
		List<Map<String, Object>> list = alarmDAO.getAlarmDataAB(hm);
		/*wangkai20141016新增故障提示开关判断，判断逻辑如下
		 * 3.6.6新增
		 * 1，从提示开关表中获取“报警提示开关”为关的设备集合
		   2，对从list进行遍历，如果存在则移除该设备的信息
		*/
		/******************获取报警提示开关为关的设备id的集合begin******************/
		List<String> AlarmPromptSwitchDown = alarmDAO.getAlarmPromtPSwitch();
		/******************获取报警提示开关为关的设备id的集合end********************/
		/*过滤报警提示开关为关的设备wangkai-20141016
		  count:过滤报警提示开关为关后的报警条数
		*/
		int count=list.size();
		for (Map<String, Object> map : list) {
			if(AlarmPromptSwitchDown.contains(MapGetter.getString(map, "MsgAlm_Vcl_ID"))){
				count--;
			}
		}
		/*LogUtil.info(this.getClass().getName(), "End -- 报警捕获结束，共捕获到‘"+list.size()+"’条报警信息！");*/
		LogUtil.info(this.getClass().getName(), "End -- 报警捕获结束，共捕获到‘"+count+"’条报警信息！");
		int xxFlt = 0;		//报警中条数；
		int xxSuc = 0;		//插入状态表成功条数
		int xxFail = 0;		//插入状态表失败条数
		int xxMsgSuc = 0;	//短信成功发送次数
		int xxMsgFail = 0;	//短信发送失败次数

		int fxxFlt = 0;		//报警解除条数；
		int fxxSuc = 0;		//报警解除成功条数；
		int fxxFail = 0;	//报警解除失败条数；
		/**2013.04.12 haoyang 添加 begin*/
		//获取25分钟前的 短信发送记录
		List<String> alarmSendRecord = smsInfoDAO.getSmsMsgBeforeSomeTime("2");
		//第二天 短信发送记录
		List<String> alarmSendRecordSecDay = smsInfoDAO.getSmsMsgSecondDay("2");
		List<String> alarmList = new ArrayList<String>();// vclId_sysAId:同一设备,同一报警类型
		/**end*/
		String mailSuje = "";//邮件主题
		String mailContent = "";//邮件内容
		for (Map<String, Object> map : list) {
			String isAlarm = MapGetter.getString(map, "MsgAlmC_IsAlarm");
			//新增-过滤报警提示开关为关的设备
			if (!AlarmPromptSwitchDown.contains(MapGetter.getString(map,"MsgAlm_Vcl_ID"))) {
				if (isAlarm.equals("true")) {// 状态：报警中
					xxFlt++;
					// 状态初始化
					boolean flag = alarmDAO.addAlarmState(map);

					// 状态初始化成功则发送报警短信
					if (flag) {
						xxSuc++;
						// 获取 短信接收人 2013.04.08 haoyang add
						// 获得设备所属机构Code值
						Map<String, Object> codeMap = malfunctionDiagnosisDAO
								.getDBCode(MapGetter.getString(map,
										"MsgAlm_Vcl_ID"));
						// 获取设备组织机构
						String DBCode = MapGetter.getString(codeMap, "DBCode");
						String VehicleID = MapGetter.getString(map,
								"MsgAlm_Vcl_ID");
						List<Map<String, Object>> userList = smsInfoDAO
								.getSMSUsers("SMSAS_SMSAlm", DBCode, VehicleID);

						// 邮件发送-------改为日报，不实时发送---------------------------

						// List<Map<String,Object>> userMailList =
						// smsInfoDAO.getSMSUsers(DBCode,
						// "SMSAS_MailAlm");//邮件接收人
						//
						// mailSuje =
						// MailCfg.getMailSujeInfo(MapGetter.getString(codeMap,
						// "VehicleNumber"),
						// MapGetter.getString(map, "MsgAlm_MsgTime"),
						// MailCfg.MailSujeAlarm); //邮件主题初始化
						//
						// mailContent =
						// SMSContentCfg.SMSCCfgAlarm.replace("X_VclNum",
						// MapGetter.getString(codeMap, "VehicleNumber"))
						// .replace("X_Date",
						// DateList.getFormatDate(MapGetter.getString(map,
						// "MsgAlm_MsgTime"),5))
						// .replace("X_Content", MapGetter.getString(map,
						// "SysA_ItemCN"));//邮件内容初始化
						//
						// SendMail.getInstance().sendMail(mailSuje,
						// mailContent, userMailList,
						// "Email");//发送邮件，暂未对发送状态进行判断处理

						// 邮件发送----------------------------------

						boolean isSuc = false;
						String uniqueID = VehicleID + "_"
								+ MapGetter.getString(map, "MsgAlmC_SysA_ID");
						if (!alarmList.contains(uniqueID)
								&& !alarmSendRecord.contains(uniqueID)
								&& !alarmSendRecordSecDay.contains(uniqueID))
							isSuc = alarmDAO.sendAlarmMsg(map, userList);
						if (isSuc) {
							xxMsgSuc++;
							alarmList.add(uniqueID);
						} else
							xxMsgFail++;
					} else {
						xxFail++;
					}

				} else if (isAlarm.equals("false")) {// 状态：已解除
					fxxFlt++;
					// 将与本条数据的设备ID、报警项相同的报警信息状态均改为0（已解除）
					boolean flag = alarmDAO.updateAlarmState(map);
					if (flag)
						fxxSuc++;
					else
						fxxFail++;
				}
			}
		}
		LogUtil.info(this.getClass().getName(), "机械报警---------处于报警中的信息共有‘"+xxFlt+"’条，插入状态表成功‘"+xxSuc+"’条，失败‘"+xxFail+"’条，‘"+xxMsgSuc+"’条报警信息发送短信成功，‘"+xxMsgFail+"’条报警信息发送短信失败；" +
				"共有报警解除数据‘"+fxxFlt+"’条，‘"+fxxSuc+"’条报警解除修改成功，‘"+fxxFail+"’条报警解除失败！");
	}
	
	//保养提醒信息初始化及短信发送
	public void calMaintForstHandle(){
		//获得保养提前提醒时间
		Map<String,Object> map = malfunctionDiagnosisDAO.getMtnAlarmHoursAndKm();
		try{
			float MtnAlarmHours = map.get("SysPC_MtnAlarmHours")!=null?Float.parseFloat(map.get("SysPC_MtnAlarmHours").toString()):50;
			float MtnAlarmKm = map.get("SysPC_MtnAlarmKm")!=null?Float.parseFloat(map.get("SysPC_MtnAlarmKm").toString()):50;
			/*****LXF    2013-06-03 ***Begin*******/   
			//保养提前提醒天数
			String SysPC_MtnAlarmDays = MapGetter.getString(map, "SysPC_MtnAlarmDays");
			int MtnAlarmDays = StringUtil.isValid(SysPC_MtnAlarmDays)?Integer.parseInt(SysPC_MtnAlarmDays):3;
			/*****LXF    2013-06-03 ***End*******/
			double istBgnMaxId = malfunctionDiagnosisDAO.getMtnAlarmInfoMaxID();
			malfunctionDiagnosisDAO.initMtnRepair_Info(MtnAlarmHours,MtnAlarmKm,MtnAlarmDays);
			double istEndMaxId = malfunctionDiagnosisDAO.getMtnAlarmInfoMaxID();
			
			//从提醒信息表中取最新数据
			List<Map<String,Object>> list = malfunctionDiagnosisDAO.getMaintData(istBgnMaxId,istEndMaxId);
			String mailSuje = "";//邮件主题
			String mailContent = "";//邮件内容
			//遍历数据
			for(Map<String,Object> hm:list){
				String SSR_MtnA_ID = hm.get("MtnA_ID")!=null?hm.get("MtnA_ID").toString():"";
				String VehicleID = hm.get("VehicleID")!=null?hm.get("VehicleID").toString():"";
				String SysMT_Type = hm.get("SysMT_Type")!=null?hm.get("SysMT_Type").toString():"";
				String SysIsm_level=hm.get("SysIsm_level")!=null?hm.get("SysMT_Type").toString():"";
				
				
				/**2013.04.09 haoyang add begin*/
				//获取短信接收人
				Map<String, Object> codeMap = malfunctionDiagnosisDAO.getDBCode(VehicleID);
				List<Map<String,Object>> userList = smsInfoDAO.getSMSUsers("SMSAS_SMSMtn",MapGetter.getString(codeMap, "DBCode"),VehicleID );
				
				//邮件发送----------------------------------
				
//				List<Map<String,Object>> userMailList = smsInfoDAO.getSMSUsers(MapGetter.getString(codeMap, "DBCode"), "SMSAS_MailMtn");//邮件接收人
				
				mailSuje = MailCfg.getMailSujeInfo(MapGetter.getString(codeMap, "VehicleNumber"),
						DateUtil.toString(DateUtil.now(), "yyyy-MM-dd HH:mm:ss"), MailCfg.MailSujeMtn); //邮件主题初始化
				
				/**end*/
//				boolean flag = false;
				if(hm.get("MtnA_AlarmHours")!=null){
					String MtnA_AlarmHours = hm.get("MtnA_AlarmHours").toString();
					
					//改为日报，不实时发送
//					mailContent = MtnFaultDao.getSendContent_M("", MapGetter.getString(codeMap, "VehicleNumber"), MtnA_AlarmHours,SysMT_Type);//邮件内容初始化
//					SendMail.getInstance().sendMail(mailSuje, mailContent, userMailList, "Email");//发送邮件，暂未对发送状态进行判断处理
					
					/**IEMS3.0 注释短信发送*/
					malfunctionDiagnosisDAO.sendMaintInfo(SSR_MtnA_ID, VehicleID, SysMT_Type, MtnA_AlarmHours,"1",userList);
				}else if(hm.get("MtnA_AlarmKm")!=null){
					String MtnA_AlarmKm = hm.get("MtnA_AlarmKm").toString();
					
					//改为日报，不实时发送
//					mailContent = MtnFaultDao.getSendContent_MKm("", MapGetter.getString(codeMap, "VehicleNumber"), MtnA_AlarmKm,SysMT_Type);//邮件内容初始化
//					SendMail.getInstance().sendMail(mailSuje, mailContent, userMailList, "Email");//发送邮件，暂未对发送状态进行判断处理
					
					/**IEMS3.0 注释短信发送*/
					malfunctionDiagnosisDAO.sendMaintInfo(SSR_MtnA_ID, VehicleID, SysMT_Type, MtnA_AlarmKm,"2",userList);
				}else if(hm.get("MtnA_AlarmDays") != null){
					//距保养天数
					String MtnA_AlarmDays = MapGetter.getString(hm, "MtnA_AlarmDays");

					//改为日报，不实时发送
//					mailContent = MtnFaultDao.getSendContent_MDays("", MapGetter.getString(codeMap, "VehicleNumber"), MtnA_AlarmDays, SysMT_Type);//邮件内容初始化
//					SendMail.getInstance().sendMail(mailSuje, mailContent, userMailList, "Email");//发送邮件，暂未对发送状态进行判断处理
					
					/**IEMS3.0 注释短信发送*/
					malfunctionDiagnosisDAO.sendMaintInfo(SSR_MtnA_ID, VehicleID, SysMT_Type, MtnA_AlarmDays,"3",userList);
				}else{
					//不做任何处理
				}
				/**添加原因不明，目前影响web保养提醒逻辑
				if(flag){
					malfunctionDiagnosisDAO.udpateAlarmInfoExp(SSR_MtnA_ID);
				}
				**/
			}
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	public List<String[]> getPositionPromt(List<String[]> vclLoLaList,String loc) {
		
		String loStrs = "";				//定义多组经度
		String laStrs = "";				//定义多组维度
		
		//定义有经度维度的列表
		List<String[]> existsLola = new ArrayList<String[]>();
		//没有的经度维度的列表
		List<String[]> noExistsLola = new ArrayList<String[]>();
		
		//循环精度纬度 分割为   有经度维度的existsLola列表和没有经度维度的noExistsLola列表
		for(String[] vclStr : vclLoLaList){
			if(!"undefined".equals(vclStr[0])){
				if(vclStr[1].equals("0.0")||vclStr[2].equals("0.0") || !StringUtil.isValid(vclStr[1]) || !StringUtil.isValid(vclStr[2])){
					/*if(loc.equals("zh_CN")){
						vclStr[1] = "未知";
					}
					if(loc.equals("en_US")){
						vclStr[1] = "Unkown";
					}
					//vclStr[1] = TeamOverViewDefault.vclPositioin;
					vclStr[2] = "";
					noExistsLola.add(vclStr);*/
				}else{
					existsLola.add(vclStr);
				}
			}
		}
		
		//拼接多组经纬度，调用地图服务
		if(existsLola.size()>0){
			for(int i=0;i<existsLola.size();i++){ 
				loStrs += existsLola.get(i)[1].toString()+",";
				laStrs  += existsLola.get(i)[2].toString()+",";
			}
			loStrs  = loStrs.substring(0,loStrs.length()-1);
			laStrs  = laStrs.substring(0,laStrs.length()-1);
		}
		
		//调用服务获得位置（分隔的位置信息，无位置信息则为""）
		String vclPositions = "";
		try{
			if(loStrs.length()>0){
				//jiyongtian 20140607 设备位置解析 不能使用附件的位置替换
//				vclPositions = MapFunction.getLngLatDescription(loStrs,laStrs);
				vclPositions = MapFunction.getPositionReviseNoReplaceDescription(loStrs, laStrs);
			}
		}catch(Exception ex){
			//调用出错
			System.out.print("调用地图服务获得位置出错，" +
					"代码位置：TeamOverViewListService.getPositionPromt(List<String[]> vclLoLaList,String loc)");
		}
		
		//分割地图并封装
		String[] vclPositionArr = new String[vclLoLaList.size()];
		vclPositionArr = vclPositions.split(",");
		
		//设备和设备位置集合 String[0] 设备号，String[1] 设备位置
		List<String[]> vclPositionList = new ArrayList<String[]>();
		//循环获得的地图位置 添加入返回集合 vclPositionList
		for(int j=0;j<existsLola.size();j++){
			String[] position = new String[2];
			position[0] = existsLola.get(j)[0];
			
			//封装地图位置
			String vclPos = "";
			//验证数组下标
			if(vclPositionArr.length>=j+1){
				vclPos =  vclPositionArr[j];
			}
			//验证是否为空
			if(!StringUtil.isNullOrEmpty(vclPos)){
				continue;
			}
			position[1] = vclPos;
			vclPositionList.add(position);
		}
		//添加没有经纬度的数据
		//vclPositionList.addAll(noExistsLola);
		
		this.poiss = vclPositionList;
		return vclPositionList;
	}
	/**处理App故障数据逻辑
	 * type:1-管理版；2-支持版
	将不同的故障类型，设备id,账户作为一条，并用map存储
	*结构：Map<String,List<Map<String,Object>>>
	*key:vehicleid 
	*value:此设备的对应人员list集合
	*字典值：1-管理版-lv2中  1:4级故障   2:3及故障   3:2级故障   4:1级故障
	*字典值：2-支持版-lv2中  5:4级故障   6:3及故障   7:2级故障   8:1级故障
	*/
	
	public Map<String,List<Map<String,Object>>> getAllUserMsgs(int type){
		List<Map<String,Object>> list=malfunctionDiagnosisDAO.getAllUserMsg(type);
		Map<String,List<Map<String,Object>>> mapAll=new HashMap<String,List<Map<String,Object>>>();
		for(Map<String,Object>map: list){
			String jsonString=MapGetter.getString(map,"as_deploycontent");
			String id = MapGetter.getString(map,"vehicleid");
			if(jsonString!=null&&!"".equals(jsonString)&&jsonString.indexOf(",")>0){
				JSONArray json=JSONArray.fromObject(jsonString);
				for(int i=0;i<json.size();i++){//遍历
					Map<String,Object>maps=new HashMap<String,Object>();
					JSONObject jsonMap=JSONObject.fromObject(json.get(i));
					String lv1=jsonMap.getString("lv1").toString();
					String lv2=jsonMap.getString("lv2").toString();
					lv2=getFltlevel(lv2,type);
					String stat =jsonMap.getString("stat").toString();
						if(stat.equals("1")&&("1".equals(lv1) || "2".equals(lv1))&&null!=lv2){
							String vehicleid=MapGetter.getString(map,"vehicleid");
							maps.put("vehicleid",MapGetter.getString(map,"vehicleid"));
							maps.put("accountid", MapGetter.getString(map,"accountid" ));
							maps.put("fltlevel",lv2);
							maps.put("vehiclenumber",MapGetter.getString(map,"vehiclenumber" ) );
							if(mapAll.get(vehicleid)==null||"".equals(mapAll.get(vehicleid))){
								List<Map<String,Object>>listAll=new ArrayList<Map<String,Object>>();
								listAll.add(maps);
								mapAll.put(vehicleid,listAll);
								
							}else{
								List<Map<String,Object>>listAll=mapAll.get(vehicleid);
								listAll.add(maps);
							}					
						}
	
				}
			}
		}
		return mapAll;
	}
	
	/**
	 * 向App故障表插入数据
	 * @param list
	 * @param hm
	 * @param sqlList
	 * @param paramList
	 * @param CloudPushlist
	 * @param mapAccountid
	 * @param type(1:管理版；2：支持版)
	 * 
	 */
	public void InsertApp(List<Map<String,Object>> list,Map<String,Object> hm,List<String>sqlList,List< Object[]> paramList,List<Map<String,Object>> CloudPushlist,Map<String,Map<String,Object>>mapAccountid,int type ){
		String FltCode = MapGetter.getString(hm, "FaultCode");
		String Fltlevel=MapGetter.getString(hm, "sysism_level");
		String VehicleID = MapGetter.getString(hm, "VehicleID"); 
		if(list!=null){
			for(Map<String,Object> maps:list){
				String Level=MapGetter.getString(maps,"fltlevel");
				String vehiclenumber=MapGetter.getString(maps,"vehiclenumber");
				if(Fltlevel.equals(Level)&&!"".equals(Fltlevel)){//此条故障应推送给App
					String Sql="INSERT INTO APP_FltMsg "+
							"(App_Flt_AccountId "+
							",App_Flt_VclId "+
							" ,App_Flt_FltCode "+
							" ,APP_Flt_fltLevle "+
							",App_Flt_FltMsgTime "+
							" ,App_Flt_fltCont  " +
							" ,App_Flt_fltAllCont " +
							" ,App_Flt_Risk " +
							" ,App_Flt_Spn " +
							" ,App_Flt_Fmi " +
							" ,App_Flt_type) " +
							" values (?,?,?,?,?,?,?,?,?,?,?)";
					sqlList.add(Sql);
					paramList.add(new Object[]{MapGetter.getString(maps,"accountid"),
							VehicleID,FltCode,Fltlevel,MapGetter.getString(hm, "MessageTime"),
							MapGetter.getString(hm,"fltism_contentcn_abbr"),
							MapGetter.getString(hm,"faultcontenti"),
							MapGetter.getString(hm,"sysism_risk"),
							MapGetter.getString(hm,"SysISM_SPN"),
							MapGetter.getString(hm,"SysISM_FMI"),
							type
					});	
					//将信息另存储，用于百度云推送
					Map<String,Object> map=new HashMap<String,Object>();
					Map<String,Object> mapUser=mapAccountid.get(MapGetter.getString(maps,"accountid"));
					String userid="";
					String chanlid="";
					//管理版
					if(1 == type){
						userid = MapGetter.getString(mapUser,"baiduID_APP");
						chanlid = MapGetter.getString(mapUser,"bdChnID_APP");
						//支持版
					} else if (2 == type){
						userid = MapGetter.getString(mapUser,"baiduID_APP_SP");
						chanlid = MapGetter.getString(mapUser,"bdChnID_APP_SP");
					}
					if(null!=userid&&!"".equals(userid)&&null!=chanlid&&!"".equals(chanlid)){
					map.put("userid", userid);//百度用户id
					map.put("chanlid", chanlid);//频道id
					map.put("risk", MapGetter.getString(hm,"sysism_risk"));//风险信息
					
					map.put("vehicleid", VehicleID);//设备id
					map.put("level",Fltlevel);//故障级别
					map.put("fltcode",FltCode);//故障code码
					map.put("fltfmi",MapGetter.getString(hm,"SysISM_FMI") );//故障fmi
					map.put("fltspn", MapGetter.getString(hm,"SysISM_SPN"));//故障spn码
					map.put("fltdetialmsg",MapGetter.getString(hm,"faultcontenti") );//
					map.put("vehiclenumber", vehiclenumber);
					CloudPushlist.add(map);
				}
				
				}
			}
		}
	}
	//获取故障级别
	public String getFltlevel(String drilevelId,int type){
		int id=Integer.parseInt(drilevelId);
		if(1 == type){
			switch (id) {
			case 1:
					return "4";
			case 2:
					return "3";
			case 3:
					return "2";
			case 4:
					return "1";
			default:
					return null;
			}
		} else if(2 == type){
			switch (id) {
			case 5:
					return "4";
			case 6:
					return "3";
			case 7:
					return "2";
			case 8:
					return "1";
			default:
					return null;
			}
		} else {
			return null;
		}

	}
}

class SelectPois implements Callable<Boolean>{
	
	private List<String[]> poi = null;
	
	SelectPois(List<String[]> poi){
		this.poi = poi;
	}
	@Override
	public Boolean call() throws Exception{
		List<String[]> pps = null;
		pps = new MtnFaultServcie().getPositionPromt(poi, "zh_CN");
		if(null != pps){
			return Boolean.TRUE;
		}else{
			return Boolean.FALSE;
		}
	}

}
